/**
 * 
 * Copyright (C) 2011 Cody Stoutenburg . All rights reserved.
 *
 *       This program is free software; you can redistribute it and/or
 *       modify it under the terms of the GNU Lesser General Public License
 *       as published by the Free Software Foundation; either version 2.1
 *       of the License, or (at your option) any later version.
 *
 *       This program is distributed in the hope that it will be useful,
 *       but WITHOUT ANY WARRANTY; without even the implied warranty of
 *       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *       GNU Lesser General Public License for more details.
 *
 *       You should have received a copy of the GNU Lesser General Public License
 *       along with this program; if not, write to the Free Software
 *       Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. 
 * 
 */
package net.alteiar.plateform.game.view;

import java.awt.Graphics2D;
import java.util.HashMap;

import net.alteiar.plateform.game.GUID;
import net.alteiar.plateform.game.Scale;
import net.alteiar.plateform.game.Vector2D;
import net.alteiar.plateform.game.model.EntityModel;
import net.alteiar.plateform.game.view.sprite.Sprite;

/**
 * @author Cody Stoutenburg
 * 
 */
public class EntityView extends GUID {

	public static final Integer SPRITE_LEFT = 1;
	public static final Integer SPRITE_RIGHT = 2;
	public static final Integer SPRITE_UP = 3;
	public static final Integer SPRITE_DOWN = 4;

	private static final Double PI_4 = Math.PI / 4.0;
	private static final Double PI_34 = 3 * Math.PI / 4.0;

	private final UiWorld world;
	private final EntityModel entity;
	private final HashMap<Integer, Sprite> sprite;

	public EntityView(UiWorld world, EntityModel model) {
		super(model.getGuid());

		this.world = world;
		this.entity = model;

		this.sprite = new HashMap<Integer, Sprite>(4);
	}

	public void addSprite(Integer direction, Sprite sprite) {
		this.sprite.put(direction, sprite);
	}

	public Sprite getSprite() {
		Integer currentDir = SPRITE_LEFT;
		Vector2D direction = this.entity.getCurrentSpeed();

		if (PI_4 < direction.getAt() && direction.getAt() < PI_34) {
			currentDir = SPRITE_DOWN;
		} else if (-PI_4 > direction.getAt() && direction.getAt() > -PI_34) {
			currentDir = SPRITE_UP;
		} else if (PI_4 > direction.getAt() && direction.getAt() > -PI_4) {
			currentDir = SPRITE_RIGHT;
		}
		return this.sprite.get(currentDir);
	}

	/**
	 * Get the x location of this entity
	 * 
	 * @return The x location of this entity
	 */
	public Double getX() {
		return entity.getX();
	}

	/**
	 * Get the y location of this entity
	 * 
	 * @return The y location of this entity
	 */
	public Double getY() {
		return entity.getY();
	}

	/**
	 * Draw this entity to the graphics context provided
	 * 
	 * @param g
	 *            The graphics context on which to draw
	 */
	public void draw(Graphics2D g) {

		Scale worldScale = this.world.getScale();

		Integer worldPixelX = Double.valueOf(
				entity.getX() * worldScale.getPixels()).intValue();
		Integer worldPixelY = Double.valueOf(
				entity.getY() * worldScale.getPixels()).intValue();

		int xOffsetPixel = this.world.getXOffsetPixel();
		int yOffsetPixel = this.world.getYOffsetPixel();

		// if the element is not visible do not draw it
		if ((xOffsetPixel < worldPixelX && worldPixelX < world.getXMaxPixel())
				&& (yOffsetPixel < worldPixelY && worldPixelY < world
						.getYMaxPixel())) {

			getSprite().draw(g, worldPixelX - xOffsetPixel,
					worldPixelY - yOffsetPixel, this.world.getFrameInMs(),
					entity.getRelativeSpeed());
		}
	}
}
